package rabbit.flt.common.trace;

import rabbit.flt.common.trace.io.HttpRequest;
import rabbit.flt.common.trace.io.HttpResponse;

import java.lang.reflect.Method;

import static rabbit.flt.common.trace.TraceData.Status.OK;

public class TraceData {

    private String traceId;

    // trace 节点名
    private String nodeName;

    /**
     * 节点描述
     */
    private String nodeDesc;

    private String spanId;

    /**
     * 请求时间
     */
    private long requestTime;

    /**
     * 当前节点ip
     */
    private String serverIp;

    // 应用编码
    private String applicationCode;

    private String sourceApplication;

    // 耗时
    private long cost;

    private Status status = OK;

    /**
     * 序号
     */
    private long index;

    public enum Status {
        OK, ERR
    }

    /**
     * 该字段在发送前直接清理掉
     */
    private Method targetMethod;

    /**
     * 输入
     */
    private HttpRequest httpRequest;

    /**
     * 输出
     */
    private HttpResponse httpResponse;

    /**
     * 消息类型
     */
    private String messageType = MessageType.METHOD.name();

    /**
     * 附加数据
     */
    private String data;

    /**
     * 是否有controller接口承接请求
     */
    private boolean hasMappedController = false;

    public String getTraceId() {
        return traceId;
    }

    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }

    public String getNodeName() {
        return nodeName;
    }

    public void setNodeName(String nodeName) {
        this.nodeName = nodeName;
    }

    public String getNodeDesc() {
        return nodeDesc;
    }

    public void setNodeDesc(String nodeDesc) {
        this.nodeDesc = nodeDesc;
    }

    public String getSpanId() {
        return spanId;
    }

    public void setSpanId(String spanId) {
        this.spanId = spanId;
    }

    public long getRequestTime() {
        return requestTime;
    }

    public void setRequestTime(long requestTime) {
        this.requestTime = requestTime;
    }

    public String getServerIp() {
        return serverIp;
    }

    public void setServerIp(String serverIp) {
        this.serverIp = serverIp;
    }

    public String getApplicationCode() {
        return applicationCode;
    }

    public void setApplicationCode(String applicationCode) {
        this.applicationCode = applicationCode;
    }

    public String getSourceApplication() {
        return sourceApplication;
    }

    public void setSourceApplication(String sourceApplication) {
        this.sourceApplication = sourceApplication;
    }

    public long getCost() {
        return cost;
    }

    public void setCost(long cost) {
        this.cost = cost;
    }

    public void updateCost() {
        setCost(System.currentTimeMillis() - requestTime);
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public HttpRequest getHttpRequest() {
        return httpRequest;
    }

    public void setHttpRequest(HttpRequest httpRequest) {
        this.httpRequest = httpRequest;
    }

    public HttpResponse getHttpResponse() {
        return httpResponse;
    }

    public void setHttpResponse(HttpResponse httpResponse) {
        this.httpResponse = httpResponse;
    }

    public String getMessageType() {
        return messageType;
    }

    public void setMessageType(String messageType) {
        this.messageType = messageType;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    /**
     * 有controller方法映射
     *
     * @return
     */
    public boolean isHasMappedController() {
        return hasMappedController;
    }

    public void setHasMappedController(boolean hasMappedController) {
        this.hasMappedController = hasMappedController;
    }

    public Method getTargetMethod() {
        return targetMethod;
    }

    public void setTargetMethod(Method targetMethod) {
        this.targetMethod = targetMethod;
    }

    public void setIndex(long index) {
        this.index = index;
    }

    /**
     * 是否属于有效的trace，超过100个节点就不发送了，避免过多trace，查询时内存溢出
     *
     * @return
     */
    public boolean isValidTrace() {
        return this.index <= 100;
    }

    /**
     * 判断trace索引是不是临界点值
     *
     * @return
     */
    public boolean isThresholdIndex() {
        return 100 == this.index;
    }
}
